/*
 * kfulles - Recognize Leaves with Android phone camera
 * Copyright (C) 2010 Oriol Piera, <oriolpiera@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Id$
 */
package com.cortsenc.kfulles;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.ByteArrayBuffer;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class kfulles extends Activity {
    /** Called when the activity is first created. */
	//Constants a modificar per mesurar el rendiment del programa
	private static int LLINDAR_VORA = 50;
	private static int MINIM_X_LINIA = 20;
	private static int PIXELS_X_PUNT = 10;
	private static int MIDA_IMATGE = 200;
	
	private static int TAKE_PICTURE = 1;
	private static int SELECT_PICTURE = 2;
	private Uri outputFileUri;
	private ImageView iv;
	private Bitmap bm;
	private String selectedImagePath;
	Preferencies mypref = null;
	ProgressBar bar;
	TextView tv1;
	TextView tv2;
	TextView tv3;
	ProgressDialog pd;

	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
        setContentView(R.layout.main);
        
        tv1 = (TextView)findViewById(R.id.resultat1);
        tv2 = (TextView)findViewById(R.id.resultat2);
        tv3 = (TextView)findViewById(R.id.resultat3);
        mypref = new Preferencies(this.getApplicationContext());

		final Button botoCaptura = (Button)findViewById(R.id.btnCamera);
		botoCaptura.setOnClickListener(new View.OnClickListener() {	
			public void onClick(View v) {
		    	  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		    	  int x = (int)System.currentTimeMillis();
		    	  File file = new File(
		    			  Environment.getExternalStorageDirectory(),
		    	          "kfulles-" + x + ".jpg");  
		    	  selectedImagePath = file.getAbsolutePath();
		    	  outputFileUri = Uri.fromFile(file);
		    	  intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
		    	  startActivityForResult(intent, TAKE_PICTURE);
			}
		});
		
		final Button botoObre = (Button)findViewById(R.id.btnOpen);
		botoObre.setOnClickListener(new View.OnClickListener() {		
			public void onClick(View v) {
				Intent intent = new Intent();
				intent.setType("image/*");
				intent.setAction(Intent.ACTION_GET_CONTENT);
				startActivityForResult(Intent.createChooser(intent,
								getString(R.string.selectpicture)),
													SELECT_PICTURE);
			}
		});
		
		final Button botoSettings = (Button)findViewById(R.id.btnSettings);
		botoSettings.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				startActivity(new Intent(v.getContext(), Opcions.class));
			}
		});
		
		final Button botoInfo = (Button)findViewById(R.id.btnInfo);
		botoInfo.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// TODO Auto-generated method stub
				showDialog(1);
			}
		});
		
		
	}
    
    @Override
    public void onStart(){
        super.onStart();
        /*
         * Comprovem si esta conectat a Internet
         */
        ConnectivityManager connec =  (ConnectivityManager)getSystemService(
        									Context.CONNECTIVITY_SERVICE);
        
        if(!(connec.getNetworkInfo(0).isConnected() || 
        		connec.getNetworkInfo(1).isConnected())){
        	showDialog(2);
        }
        
    }
    protected AlertDialog onCreateDialog(int id) {
    	AlertDialog.Builder dialog;
        switch(id) {
        case 1:{//botoInfo
            // do the work to define the pause Dialog
        	dialog = new AlertDialog.Builder(this);
        	dialog.setTitle("kfulles");
        	dialog.setMessage(getString(R.string.infomessage));
        	dialog.setIcon(R.drawable.icon);
        	dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        		public void onClick(DialogInterface dialog, int id) {
        			dialog.cancel();
               }
        	});
        	//dialog.setMessage("Are you sure you want to exit?");
        }break;
        case 2:{
        	dialog = new AlertDialog.Builder(this);
        	dialog.setTitle("kfulles");
        	dialog.setMessage(getString(R.string.infonetwork));
        	dialog.setIcon(R.drawable.icon);
        	dialog.setPositiveButton("Continua", new DialogInterface.OnClickListener() {
        		public void onClick(DialogInterface dialog, int id) {
        			dialog.cancel();
               }
        	});
        	dialog.setNegativeButton("Tanca", new DialogInterface.OnClickListener() {
        		public void onClick(DialogInterface dialog, int id) {
        			try {
						kfulles.this.finish();
					} catch (Throwable e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
               }
        	});
        }break;
        default:
            dialog = null;
        }
        return dialog.create();
    }
    
    @Override
    protected void onActivityResult(int requestCode,
                                    int resultCode, Intent data) {
    		bm = null;
    		if(resultCode == RESULT_OK){
		      if (requestCode == TAKE_PICTURE) {
		    	  try {
		    		  bm = escala(MediaStore.Images.Media.getBitmap(
		    				  		getContentResolver(), outputFileUri));
		    	  } catch (FileNotFoundException e) {
		    		  e.printStackTrace();
		    	  } catch (IOException e) {
		    		  e.printStackTrace();
		    	  }
		      }
		      else if(requestCode == SELECT_PICTURE){
		    	  Uri selectedImageUri = data.getData();
		          selectedImagePath = getPath(selectedImageUri);
		          bm = escala(BitmapFactory.decodeFile(selectedImagePath));
		      }
		      if(requestCode == TAKE_PICTURE || requestCode == SELECT_PICTURE){
		    	  pd = ProgressDialog.show(this, 
		    			  		getString(R.string.titleimageproces), 
		    			  		getString(R.string.messageimageproces));
			      new Tractament().execute(bm, mypref, selectedImagePath, bar);
			        
		      }
    		}
    }
    
    /*
     * Mètode que retorna un Bitmap a la mida indicada 
     * per la constant MIDA_IMATGE
     */
    private Bitmap escala(Bitmap bm2) {
		// TODO Auto-generated method stub
    	int currentWidth = bm2.getWidth();
    	int currentHeigth = bm2.getHeight();
    	
    	int newHeigth = MIDA_IMATGE;
    	
    	if(currentWidth == newHeigth) return bm2;
    	
    	float scaleHeigth = ((float)newHeigth)/currentHeigth;
    	float scaleWidth = scaleHeigth;
    	
    	Matrix matrix = new Matrix();
    	matrix.postScale(scaleWidth, scaleHeigth);
    	
    	Bitmap resizedBitmap = Bitmap.createBitmap(bm2, 0, 0, currentWidth,
    											currentHeigth, matrix, true);
    	
		return resizedBitmap;
	}

	private String getPath(Uri selectedImageUri) {
		// TODO Auto-generated method stub
    	String[] projection = { MediaStore.Images.Media.DATA };
    	Cursor cursor = managedQuery(selectedImageUri, projection,
    											null, null, null);
    	int column_index = cursor.getColumnIndexOrThrow(
    											MediaStore.Images.Media.DATA);
    	cursor.moveToFirst();
    	String s = cursor.getString(column_index);
    	cursor.close();
    	return s;
	}
	
	private class Tractament extends AsyncTask<Object, Integer, String>{
		
		Preferencies mypref = null;
		
		final String webServidor = "http://kfulles.ateneupopulardelescorts.org/";//Servidor extern
		//final String webServidor = "http://192.168.2.195/kfulles/";//Servidor local a casa
		//final String webServidor = "http://192.168.98.142/kfulles/";//Servidor local a classe
	     
		@Override
		protected String doInBackground(Object... p) {			
			String resposta = null;
			mypref = (Preferencies)p[1];	
			ImatgeFulla imf = new ImatgeFulla((Bitmap)p[0]);
			imf.edgeDetect(LLINDAR_VORA);
	        imf.aprimar();
	        imf.checkLines(MINIM_X_LINIA);
	        imf.markPoints(PIXELS_X_PUNT);
	        imf.calcAngels();
			ArrayList<PuntFulla> leafTokens = imf.getTokens();
	        String s = "";
	        for(int i = 0; i<leafTokens.size();i++){
	        	s = s + leafTokens.get(i).getSin() + ";" + 
	        				leafTokens.get(i).getCos() + ";";
	        }
	        
	        /*
	         * Comprovem si esta en mode col·laborador
	         * Cert: Mode col·laborador, pugem la fulla al servidor
	         * Fals: Mode consulta, consultem els valors amb el servidor
	         */
	        if(mypref.getUploader()){
	      		File file = new File((String)p[2]);
	      		try {
	                HttpClient client = new DefaultHttpClient();  
	                HttpPost post = new HttpPost(webServidor+"provaenvia.php");
	                FileBody bin = new FileBody(file);
	                StringBody sbod = new StringBody(s);
	                MultipartEntity reqEntity = new MultipartEntity(
	                					HttpMultipartMode.BROWSER_COMPATIBLE);
	                reqEntity.addPart("myFile", bin);
	                reqEntity.addPart("tokens", sbod);
	                post.setEntity(reqEntity);
	                HttpResponse response = client.execute(post);  

	                InputStream is = response.getEntity().getContent();
	                BufferedInputStream bis = new BufferedInputStream(is);
	                ByteArrayBuffer baf = new ByteArrayBuffer(20);

	                 int current = 0;  
	                 while((current = bis.read()) != -1){  
	                        baf.append((byte)current);  
	                 }  
	                   
	                //Converteix els bytes a string
	                String text = new String(baf.toByteArray());
	                if(text.length()<2){
	                	resposta=getString(R.string.scriptservererror);
	                }
	                else{
	                	resposta=text;
	                }
	        	} catch (Exception e) {
	        		e.printStackTrace();
	        		resposta=e.getMessage();
	        	}
	        }
	        else{                    	
	            HttpClient httpclient = new DefaultHttpClient();
	            HttpPost httppost = new HttpPost(webServidor+
	            								"provaconsulta.php");
	            
	            try {
	           		List<NameValuePair> nameValuePairs = 
	           						new ArrayList<NameValuePair>(200);
	           		for(int x = 0; x<leafTokens.size();x++){
	           			nameValuePairs.add(new BasicNameValuePair("sin"+x, 
	           					String.valueOf(leafTokens.get(x).getSin())));
	           			nameValuePairs.add(new BasicNameValuePair("cos"+x, 
	           					String.valueOf(leafTokens.get(x).getCos())));
	           		}

	                httppost.setEntity(
	                		new UrlEncodedFormEntity(nameValuePairs));
	                HttpResponse response = httpclient.execute(httppost);
	                InputStream is = response.getEntity().getContent();
	                BufferedInputStream bis = new BufferedInputStream(is);
	                ByteArrayBuffer baf = new ByteArrayBuffer(20);

	                int current = 0;  
	                while((current = bis.read()) != -1){  
	                	baf.append((byte)current);  
	                }  
	                   
	                //Converteix els bytes a string 
	                String text = new String(baf.toByteArray());
	                if(text.length()<2){
	                	resposta=getString(R.string.scriptservererror);
	                }
	                else{
	                	resposta=text;
	                }
	            } catch (ClientProtocolException e) {
	                e.printStackTrace();
	                resposta= e.getMessage();
	            } catch (IOException e) {
	                e.printStackTrace();
	                resposta=e.getMessage();
	            } catch (Exception e){
	            	resposta=e.getMessage();
	            }   
	        }
			return resposta;
		}
		
        @Override
        protected void onPostExecute(String resposta) {
        	String[] resp = resposta.split(";");
        	pd.dismiss();
        	if(resp.length>1){
        		tv1.setText(resp[0]);
        		tv2.setText(resp[1]);
        		tv3.setText("En un " + resp[2] + "% de possibilitats");
        	}
        	else{
        		tv3.setText(resp[0]);
        	}
        	
            super.onPostExecute(resposta);
        }
	}
}